// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: implementation of CImplActionWithOnDemandBindings.
//   $Id$



#include "stdafx.h"
#include "ImplActionWithOnDemandBindings.h"
#include "XFormsElement.h"
#include "GetEnclosingBindingOf.h"
#include "XFormsXFormsElement.h"
#include "SingleNodeBinding.h"
CImplActionWithOnDemandBindings::CImplActionWithOnDemandBindings()
:m_pContextParent(0)
{

}
 
CImplActionWithOnDemandBindings::~CImplActionWithOnDemandBindings()
{

}

HRESULT CImplActionWithOnDemandBindings::ResolveContextParent()
{
	HRESULT hr = S_FALSE;

	// If there is no parent when lets try and resolve
	// its parent now.
	if(!m_pParentImpl)
		if(m_pXFormsElement)
			m_pXFormsElement->ResolveEnclosingBinding();
	CImplNodeBinding * pReturnedContext = 0;
	CImplModel * pModel = 0;
	hr = ::GetEnclosingBindingOf(this,&pReturnedContext,&pModel);
	if(pReturnedContext)
		m_pContextParent = dynamic_cast<CImplSingleNodeBinding*>(pReturnedContext);
	else if(!m_pModel)
		const_cast<CImplModel *>(m_pModel) = pModel;
	return hr;
}

HRESULT CImplActionWithOnDemandBindings::init(CImpl * pParent)
{
	HRESULT hr = ResolveEvaluationContext();
	if(SUCCEEDED(hr))
	{
		ResolveBindings();
	}
	hr = __super::init(pParent);
	return hr;
}

HRESULT CImplActionWithOnDemandBindings::ResolveEvaluationContext()
{
	HRESULT hr = ResolveContextParent();
	if(SUCCEEDED(hr))
	{
		hr = ResolveModel();
	}
	return hr;
}


HRESULT CImplActionWithOnDemandBindings::ResolveModel()
{
	HRESULT hr = E_FAIL;
	//First call for resolving the model is to 
	//	get the model named in the model attribute.
	if(m_sModel)
	{
		if(m_pXForms)
		{
			CImplModel * pModel;
			m_pXForms->getModel(m_sModel,pModel);
			const_cast<CImplModel *>(m_pModel) = pModel;
			m_bHasResolvedOwnModel = true;
		}
	}
	//Then, attempt to resolve it through the context parent.
	else if(m_pContextParent)
	{
		if(!m_pContextParent->m_pModel)
			m_pContextParent->getModel();

		if(m_pContextParent->m_pModel)
			const_cast<CImplModel*>(m_pModel) = m_pContextParent->m_pModel;
	}
	else if(m_pModel)
	{
		//do nothing
	}
	//Failing that, try to fetch the document's default model.
	else
	{
		CImplModel * pModel;
		m_pXForms->getModel(0,pModel);
		const_cast<CImplModel *>(m_pModel) = pModel;
	}

	if(m_pModel)
	{
		CImplModel * pModel = const_cast<CImplModel *>(m_pModel);
		__super::setModel(pModel);
		hr = S_OK;
	}

	return hr;
}
